package com.sailing.xjpb.common.web.translate;

import com.sailing.xjpb.common.SailingReflectionUtils;
import org.springframework.core.Ordered;
import org.springframework.data.domain.Page;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 翻译处理器：翻译VO中标注有相关注解的字段进行业务翻译。
 *
 * @author YaoWei
 */
public interface TranslateHandler extends Ordered {

    /**
     * 单个对象翻译
     *
     * @param t 需要翻译的数据对象
     */
    default void doTranslate(Object t) {
        if (t == null) {
            return;
        }
        Collection<?> datas;
        if (t instanceof Collection) {
            datas = (Collection<?>) t;
        } else if (t instanceof Page) {
            Page<?> page = (Page<?>) t;
            datas = page.getContent();
        } else {
            datas = Collections.singletonList(t);
        }
        if (!datas.isEmpty()) {
            this.doTranslate(datas);
        }
    }

    /**
     * 集合对象翻译
     *
     * @param datas 集合
     */
    default void doTranslate(Collection<?> datas) {
        if (datas == null || datas.isEmpty()) {
            return;
        }
        Class<?> itemClass = SailingReflectionUtils.getItemClass(datas);
        this.doTranslate(itemClass, datas);
    }

    /**
     * 集合对象翻译
     *
     * @param itemClass 集合元素类型
     * @param datas     集合元素
     */
    default void doTranslate(Class<?> itemClass, Collection<?> datas) {
        List<Field> translateFields = SailingReflectionUtils.getDeclaredFields(itemClass, getTranslateFieldFilter());
        if (!translateFields.isEmpty()) {
            this.doTranslate(itemClass, translateFields, datas);
        }
    }

    /**
     * 翻译标注有相关注解字段
     *
     * @param itemClass       集合对象类型
     * @param translateFields 需要翻译的类字段信息
     * @param datas           需要翻译的数据
     */
    void doTranslate(Class<?> itemClass, List<Field> translateFields, Collection<?> datas);

    /**
     * 字段过滤器：获取类中需要翻译的字段信息
     */
    SailingReflectionUtils.FieldFilter getTranslateFieldFilter();

}
